package com.tankwar.core;

import java.util.ArrayList;
import java.util.List;

import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.input.KeyEvent;
import javafx.scene.input.MouseEvent;
import javafx.util.Duration;

/**
 * 舞台
 * 
 * @author lifeng
 * @date 2020年4月18日 下午6:16:04
 */
public class Arena extends Canvas {

	/**
	 * 所有的可绘制对象
	 */
	private List<Hodler> drawAbles = new ArrayList<>();

	/**
	 * 时间线
	 */
	private Timeline timeline;
	private KeyFrame keyFrame;

	/**
	 * 刷新时间
	 */
	private int duration = 10;

	/**
	 * 创建舞台
	 * 
	 * @param width  宽度
	 * @param height 高度
	 */
	public Arena(double width, double height) {
		super(width, height);
		init();
	}

	/**
	 * 初始化
	 */
	private void init() {
		timeline = new Timeline();
		timeline.setCycleCount(Timeline.INDEFINITE);

		keyFrame = new KeyFrame(Duration.millis(duration), new EventHandler<ActionEvent>() {
			@Override
			public void handle(ActionEvent arg0) {
				draw(getGraphicsContext2D());
				update();
			}
		});
		timeline.getKeyFrames().add(keyFrame);
	}

	/**
	 * 开启时间线
	 */
	public void start() {
		timeline.play();
	}

	/**
	 * 暂停时间线
	 */
	public void pause() {
		timeline.pause();
	}

	/**
	 * 停止时间线
	 */
	public void stop() {
		timeline.stop();
	}

	/**
	 * 添加绘制对象
	 * 
	 * @param drawAble 可绘制的对象
	 */
	public void addDrawAble(DrawAble drawAble) {
		this.drawAbles.add(new Hodler(drawAble));
	}

	/**
	 * 绘制显示
	 */
	protected void draw(GraphicsContext gc) {
		gc.setEffect(null);
		gc.clearRect(0, 0, getWidth(), getHeight());
		for (int i = 0; i < drawAbles.size(); i++) {
			DrawAble wObject = drawAbles.get(i);
			wObject.draw(gc);
		}
	}

	/**
	 * 更新数据
	 */
	protected void update() {
		for (int i = 0; i < drawAbles.size(); i++) {
			DrawAble wObject = drawAbles.get(i);
			wObject.update();
		}
	}

	/**
	 * 事件管理器触发
	 * 
	 * @param event
	 */
	public void onKeyPressed(KeyEvent event) {
		for (int i = 0; i < drawAbles.size(); i++) {
			EventAble wObject = drawAbles.get(i);
			wObject.onKeyPressed(event);
		}
	}

	/**
	 * 事件管理器触发
	 * 
	 * @param event
	 */
	public void onKeyReleased(KeyEvent event) {
		for (int i = 0; i < drawAbles.size(); i++) {
			EventAble wObject = drawAbles.get(i);
			wObject.onKeyReleased(event);
		}
	}

	/**
	 * 事件管理器触发
	 * 
	 * @param event
	 */
	public void onMouseMoved(MouseEvent event) {
		for (int i = 0; i < drawAbles.size(); i++) {
			EventAble wObject = drawAbles.get(i);
			wObject.onMouseMoved(event);
		}
	}

	/**
	 * 中心点偏移
	 * 
	 * @param offset
	 * @return
	 */
	public double centerWidthOffset(double offset) {
		return this.getWidth() / 2 + offset;
	}

	/**
	 * 中心点偏移
	 * 
	 * @param offset
	 * @return
	 */
	public double centerHeightOffset(double offset) {
		return this.getHeight() / 2 + offset;
	}

	/**
	 * 给定的区域在里面
	 * 
	 * @param x
	 * @param y
	 * @param width
	 * @param height
	 * @return
	 */
	public boolean contain(double x, double y, double width, double height) {
		if (x >= 0 && y >= 0 && x + width <= this.getWidth() && y + height <= this.getHeight()) {
			return true;
		}
		return false;
	}

	/**
	 * 集成了事件
	 * 
	 * @author lifeng
	 * @date 2020年4月18日 下午6:59:35
	 */
	class Hodler implements EventAble, DrawAble {
		private DrawAble drawAble;
		private EventAble eventAble;

		Hodler(DrawAble drawAble) {
			this.drawAble = drawAble;
			this.eventAble = drawAble instanceof EventAble ? (EventAble) drawAble : null;
		}

		@Override
		public void onKeyPressed(KeyEvent event) {
			if (eventAble != null) {
				eventAble.onKeyPressed(event);
			}
		}

		@Override
		public void onKeyReleased(KeyEvent event) {
			if (eventAble != null) {
				eventAble.onKeyReleased(event);
			}
		}

		@Override
		public void onMouseMoved(MouseEvent event) {
			if (eventAble != null) {
				eventAble.onMouseMoved(event);
			}
		}

		@Override
		public void draw(GraphicsContext gc) {
			drawAble.draw(gc);
		}

		@Override
		public void update() {
			drawAble.update();
		}
	}
}
